#!/usr/bin/python
# -*- coding: utf-8 -*-

import maya.cmds as mc

class LZ_realistBodySys_commands():
    
    
    #----------------------   make zero group base know objection ------------------------------
    def makeZeroGrpTwo(self,OrgObj = [''],sufname='zero',cenObj='',Mode=0,type = 'group',ro =True):    #  type = 'group'   or type  ='joint'
    #   mode == 1:  replace;  mode == 0:  add  
        seleobj=mc.ls(sl=True)
        group_all =[]

        for i in OrgObj:
            if cenObj=='':
                cenParent=i
            else:
                cenParent=cenObj
            if Mode==0:
                groupname=str(i)+sufname
            if Mode==1:
                regName=str(i).split('_')
                groupname=str(i).replace(regName[-1],sufname)
                
            if type == 'group':
                mc.group(n=groupname,em=True)
            elif type == 'joint':
                mc.select(cl=True)
                mc.joint( n =groupname )
            parent=mc.listRelatives(i,p=True)
            mc.pointConstraint(cenParent,groupname,mo=False,n='needDeleteConstriant',w=1)
            mc.delete('needDeleteConstriant')
            if ro == True:
                mc.orientConstraint(cenParent,groupname,mo=False,n='needDeleteConstriant',w=1)
                
                mc.delete('needDeleteConstriant')
                
                if type =='joint':
                    self.frozeen_jnt_Transform( groupname )
            mc.parent(i,groupname)
            if parent==None:
                pass
            else:
                mc.parent(groupname,parent)
                
            group_all.append(groupname)
        mc.select(OrgObj)
        return(group_all)
    ##----------------------------------------------------------------------------------------------
    def createTransformer(self,locName = '',position = ( 0,0,0),rotation = ( 0,0,0) ,type = 'locator',LocPosion = (0,0,0)):
        if type =='locator': 
            mc.spaceLocator(  n = locName ,p = LocPosion )
        elif type =='group':
            mc.group( em = True , n= locName)
        mc.move( position[0], position[1],position[2], locName )
        mc.rotate( rotation[0], rotation[1],rotation[2], locName )
        
    
    
    def snapObj2Aim(self,obj = '' ,aimobj ='' , Translate = True ,rotation = True):
    
        if Translate == True :
            mc.pointConstraint( aimobj , obj ,mo = False , n ='deleteCon')
            mc.delete( 'deleteCon')
        if rotation ==True :
            mc.orientConstraint( aimobj , obj ,mo = False , n ='deleteCon')
            mc.delete( 'deleteCon')
    
    def clear_channelBox_Transform(self,obj=''):
        baseAttr = ['translateX','translateY','translateZ','rotateX','rotateY','rotateZ']
        
        for ba in baseAttr:
            if mc.getAttr(str(obj)+'.'+str(ba),lock=True) ==False:
                mc.setAttr(str(obj)+'.'+str(ba),0)
                
    def frozeen_jnt_Transform(self,obj=''):
        if mc.nodeType(obj) == 'joint':
            mc.makeIdentity(obj,apply=True,r=True)
            #baseAttr = ['rotateX','rotateY','rotateZ']
            #
            #for ba in baseAttr:
            #    if mc.getAttr(str(obj)+'.'+str(ba),lock=True) ==False:
            #        value = mc.getAttr( str(obj)+'.'+str(ba) )
            #        
            #        
            #        orientAttr  = 'jointOrient' + ba[-1]
            #        curentValue = mc.getAttr( str(obj)+'.'+str(orientAttr) )
            #        
            #        mc.setAttr( str(obj)+'.'+str(orientAttr) , curentValue + value )
            #        
            #        mc.setAttr(str(obj)+'.'+str(ba),0)
            #    
    def LZ_creatJoint(self,parentConsobj,jntname):
        mc.select(cl=True)
        mc.joint(n=jntname)
        mc.parentConstraint(parentConsobj,jntname,mo=False,n='templeconstraint')
        mc.delete('templeconstraint')
        secjntRX=mc.getAttr(str(jntname)+'.rx')
        secjntRY=mc.getAttr(str(jntname)+'.ry')
        secjntRZ=mc.getAttr(str(jntname)+'.rz')
        
        mc.setAttr(str(jntname)+'.jointOrient',secjntRX,secjntRY,secjntRZ)
        mc.setAttr(str(jntname)+'.rotate',0,0,0)
        
    def LZ_createJnt_byInfo(self,jntName = '', translateInfo = (0,0,0),rotateInfo = (0,0,0)):
        mc.select(cl=True)
        mc.joint(n=jntName)
        
        mc.move(translateInfo[0],translateInfo[1],translateInfo[2],jntName)
        
        if rotateInfo != None:
            mc.setAttr(str(jntName) + '.jointOrientX' , rotateInfo[0])
            mc.setAttr(str(jntName) + '.jointOrientY' , rotateInfo[1])
            mc.setAttr(str(jntName) + '.jointOrientZ' , rotateInfo[2])
    
    def LZ_createLocator_byInfo(self,locatorName = '', translateInfo = (0,0,0),rotateInfo = (0,0,0)):
        mc.select(cl=True)
        mc.spaceLocator(n=locatorName)
        
        mc.move(translateInfo[0],translateInfo[1],translateInfo[2],locatorName)
        
        if rotateInfo != None:
            mc.setAttr(str(locatorName) + '.rotateX' , rotateInfo[0])
            mc.setAttr(str(locatorName) + '.rotateY' , rotateInfo[1])
            mc.setAttr(str(locatorName) + '.rotateZ' , rotateInfo[2])
    def locator_Vis_scale(self,locatorname = '',Visscle = 1):
    
        mc.setAttr(str(locatorname)+ '.localScaleX',Visscle )
        mc.setAttr(str(locatorname)+ '.localScaleY',Visscle )
        mc.setAttr(str(locatorname)+ '.localScaleZ',Visscle )
    
    
    
    
    def deletePreName(self,oriName = '',deletePre = ''):
        splitName = str(oriName).split(deletePre)
        
        newName = ''
        for sn in splitName:
            newName = newName+sn
            
        return(newName)
    
    
    
        ###### ------------------------ get Objection World position ----------------------    
    def getWorldPosition(self,objname):
        positionWorld=mc.xform(objname,q=True,ws=True,t=True)
        return(positionWorld)
    def disBetweenPoints(self,posOne=[0,0,0],posTwo=[1,1,1]):
        disBetween=math.sqrt((posTwo[0]-posOne[0])**2+(posTwo[1]-posOne[1])**2+(posTwo[2]-posOne[2])**2)
        return(disBetween)
        
    def createStraightLine(self,curvename = '' , LocationInfo = [(0,0,0),(1,1,1)]):
        numInfo  = len(LocationInfo)
        
        k_point = []
        for num in range(numInfo) :
            k_point.append(num)
        
        mc.curve( n=curvename, p=LocationInfo, k=k_point,d=1 )
    def referenceCurve(self,obj = '' ):
    
        curveShape = mc.listRelatives(obj,s=True)[0]
        mc.setAttr(str(curveShape)+'.overrideEnabled' , 1 )
        mc.setAttr(str(curveShape)+'.overrideDisplayType' , 2 )
        
        ## -----------------------------------------------------------------------------------------
        
    def lockAttr(self,obj = '' ,attr =['']):


        for at in attr:

                mc.setAttr(obj+'.'+ at, lock=True ,keyable = False ,channelBox = False)
                
    
    def addAttrs(self,objname=[''],attrname='fuck',dv=0,key=1):
        if objname==None:
            objs=mc.ls(sl=True)
        if objname!=None:
            objs=objname
            
        for i in objs:
    
            mc.addAttr(i,longName=attrname,defaultValue=dv,k=1)
            if key == 0:
                mc.setAttr(str(i)+'.'+attrname,l=True)
                

    def FG_addAttrs(self,objname=[''],attrname='fuck',dv=0,key=1,minValue=0,maxValue=1):
        if objname==None:
            objs=mc.ls(sl=True)
        if objname!=None:
            objs=objname
            
        for i in objs:
    
            mc.addAttr(i,longName=attrname,defaultValue=dv,k=1)
            if key == 0:
                mc.setAttr(str(i)+'.'+attrname,l=True)
            
            if minValue != None:
                mc.addAttr(str(i)+'.'+attrname,e=True,min=minValue)
            if maxValue != None:
                mc.addAttr(str(i)+'.'+attrname,e=True,max=maxValue)
                
    #----------------------   add attribute (enum) ------------------------------    
    def addEnumAttr(self,objname=['nurbsSphere1'],attrname='fuck',enumMember='fuck:',key=0):
        if objname==None:
            objs=mc.ls(sl=True)
        if objname!=None:
            objs=objname
            
        for i in objs:
            mc.addAttr(i,longName=attrname,at='enum',en=enumMember,k=1)
            if key == 0:
                mc.setAttr(str(i)+'.'+attrname,l=True)
    
    
    '''
        =========================================================
        ||                                                     ||
        ||驱动关键帧 部分 的 commands                          ||
        ||the part of set driven keyFrame                      ||
        ||                                                     ||
        =========================================================
    '''  
    
    
    def setDrivenKey(self,driverAttr,drivenAttr,driverV,drivenV):

        mc.setDrivenKeyframe(drivenAttr, cd=driverAttr,dv=driverV,v=drivenV)   
        
    def  facial_keytangent_type(self,animCurve = '', type='linear'):
        if 'animCurve' in mc.nodeType(animCurve) :
            mc.keyTangent(animCurve,itt =type,ott=type)
        else:
            print ('please make sure the object input is  animationCurve')
    '''
    getSDKconnectionInfo(string ,driven)                string is a XXX.attribute   driven is a object name
    
    getSDKconnectionInfo('xxx.translateX' ,'sphere1')   
    '''    
    def getSDKconnectionInfo(self,driver,driven):
    
        drivers=mc.setDrivenKeyframe(driven,q=1,dr=1)
        drivenAttrs=mc.setDrivenKeyframe(driven,q=1,dn=1)
        
        AnimaCurve=[]
        driverAnimaCurve=[]
        driverCurves=[]
        
        SDKconnectionInfoAll=[]
        
        if driver in drivers:
            driverChilddren=mc.listConnections(driver,d=True,s=False)
            
            for dcr in driverChilddren:
                if mc.nodeType(dcr)=='unitConversion':
                    anicurve=mc.listConnections(str(dcr)+'.output',d=True)[0]
                    driverCurves.append(anicurve)
                elif 'animCurve' in mc.nodeType(dcr):
                    driverCurves.append(dcr)
                    
        
        for aa in drivenAttrs:
            sourceConnection=mc.listConnections(str(driven),s=True)
            
            if sourceConnection !=None:
                for sc in sourceConnection:
                
                    if 'animCurve' in mc.nodeType(sc):
                        if  sc not in AnimaCurve:
                            AnimaCurve.append(sc)
                    elif mc.nodeType(sc)=='blendWeighted':
                        curves=mc.listConnections(str(sc)+'.input',s=True)
                        for cvs in curves:
                            if  cvs not in AnimaCurve:
                                AnimaCurve.append(cvs)
                    elif mc.nodeType(sc)=='unitConversion':
                        uniInput=mc.listConnections(str(sc)+'.input',s=True)[0]
                        if mc.nodeType(uniInput)=='blendWeighted':
                            bwinput=mc.listConnections(str(uniInput)+'.input',s=True)
                            for bwi in bwinput:
                                if 'animCurve' in mc.nodeType(bwi):
                                    if  bwi not in AnimaCurve:
                                        AnimaCurve.append(bwi)
                                if mc.nodeType(bwi)=='unitConversion':
                                    bwiuniInput=mc.listConnections(str(bwi)+'.input',s=True)[0]
                                    if 'animCurve' in mc.nodeType(bwiuniInput):
                                        if  bwiuniInput not in AnimaCurve:
                                            AnimaCurve.append(bwiuniInput)
                            
        
        for ac in AnimaCurve:
            if ac in driverCurves:
                driverAnimaCurve.append(ac)
        for dac in driverAnimaCurve:
            destinationAttr='none'
            destination=mc.listConnections(str(dac)+'.output',d=True,skipConversionNodes=True)[0]
            if mc.nodeType(destination)=='blendWeighted':
                destinationAttr=mc.listConnections(str(destination)+'.output',d=True,p=True)[0]
            elif mc.nodeType(destination)=='transform' or mc.nodeType(destination)=='blendShape' or mc.nodeType(destination)=='joint':
                
                destinationAttr=mc.listConnections(str(dac)+'.output',d=True,p=True)[0]
            
            else:
                inputAttr=mc.listConnections(str(dac)+'.output',d=True,p=True)[0]
                
                inputObj=str(inputAttr).split('.')[0]
                
                if mc.nodeType(inputObj)=='unitConversion':
                    inoutBlendweight=mc.listConnections(str(inputObj)+'.output',d=True)[0]
                    Blendweightout=mc.listConnections(str(inoutBlendweight)+'.output',d=True)[0]
                    destinationAttr=mc.listConnections(str(Blendweightout)+'.output',d=True,p=True)[0]
                elif mc.nodeType(inputObj)=='blendWeighted':
                    destinationAttr=mc.listConnections(str(destination)+'.output',d=True,p=True)[0]
            
                
            SDKconnectionInfo=[driver,dac,destinationAttr]
            
            SDKconnectionInfoAll.append(SDKconnectionInfo)
        return SDKconnectionInfoAll
    
    ####################################################################################################
    #------------------------------- create inverseMatrix   ------------------------------------------
    
    '''
        =========================================================
        ||                                                     ||
        ||逆矩阵 部分 的 commands                              ||
        ||the part of inverseMatrix                            ||
        ||                                                     ||
        =========================================================
    '''  
    
    def getSkinCluster(self,objname = ''):
        InputSkinCluster = mc.ls(mc.listHistory( objname ),type='skinCluster')[0]
        return InputSkinCluster
    
    def createReverseJnt(self,objname = '' ,stept = 1):
        


        reversename=str(objname) + '_reverse'
        
        mc.duplicate(objname,n=reversename)
        mc.setAttr(str(reversename)+'.visibility',0)
        if stept>1:
            parentname = mc.listRelatives(objname , p=True )[0]
            mc.parent(reversename,parentname)
            
        return reversename
    def conneReverseAttr(self,skinname , IsAllCluters):
        

        jntConnectAll=[]
        worldMatrixAttr=[]
        
        # skinname='skinCluster6'
        connectAttrs=mc.listConnections(skinname,s=True,p=True,c=True,scn=True)
        for m in connectAttrs:
            if 'worldMatrix' in m:
                worldMatrixAttr.append(m)
        for i in worldMatrixAttr:
            ojbConnect=str(i).split('.')[0]
            jntConnectAll.append(ojbConnect)

            
            if IsAllCluters == 1:
    
    
    
                connectedMatrixAttr=mc.listConnections(i,d=True,p=True)
    
          
                for k in connectedMatrixAttr:
                
            
                    bindAttr=str(k).replace('matrix','bindPreMatrix')
                    splitname=str(ojbConnect).split('_')
                    reversename=str(ojbConnect) + '_reverse'
            
                    attrIsConnect=mc.listConnections(bindAttr,s=True)
                    if attrIsConnect==None: 
                        mc.connectAttr(str(reversename)+'.worldInverseMatrix[0]',bindAttr)

                        
            if IsAllCluters == 0:
                connectedMatrixAttr=mc.listConnections(i,d=True,p=True)[0]
                
                orgbindAttr=str(connectedMatrixAttr).replace('matrix','bindPreMatrix')
                replacename=str(connectedMatrixAttr).split('.')[0]
                bindAttr=str(orgbindAttr).replace(replacename,skinname)
                
                splitname=str(ojbConnect).split('_')
                reversename=str(ojbConnect) + '_reverse'
            
                attrIsConnect=mc.listConnections(bindAttr,s=True)
                if attrIsConnect==None: 
                    mc.connectAttr(str(reversename)+'.worldInverseMatrix[0]',bindAttr)
                    
    '''
        =========================================================
        ||                                                     ||
        ||得到极向量控制器的方向 的 commands                   ||
        ||the part of poleVector                               ||
        ||                                                     ||
        =========================================================
    '''                 
    def getPoleVector(self,ikhandle = '',locatorTemple = '' ):
        #get ikhandle if you selected.
        ikh = ikhandle



        #for ikh in ikhs:
            
        startJnt = mc.listConnections(str(ikh)+'.startJoint' , p=False)
        endJnt = mc.listConnections(str(ikh)+'.endEffector' , p=False)
        elbowORkneeJnt = mc.listRelatives(startJnt[0],ad=1,type='joint')
        elbowORkneeJnt.reverse()
        startJntPos = mc.joint(elbowORkneeJnt[0],q=True,p=True)
        
        #get poleVector date.        
        poleVecX = mc.getAttr(str(ikh)+'.poleVectorX')*1
        poleVecY = mc.getAttr(str(ikh)+'.poleVectorY')*1
        poleVecZ = mc.getAttr(str(ikh)+'.poleVectorZ')*1
        
        
        
        #  create locator
        aimLoc = 'temple_needdelete_loc'
        
        mc.spaceLocator(n=locatorTemple )
        
        '''
        ``````````````````````````````
        
        '''
        pointC = 'pointConstraint_temple'
        aimC = 'aimConstraint_temple'
        mc.pointConstraint( startJnt,endJnt ,locatorTemple ,n = pointC )
        mc.aimConstraint( endJnt  ,locatorTemple  ,worldUpType='object',worldUpObject = elbowORkneeJnt[0] , n =aimC)
        
        mc.delete( pointC )
        mc.delete( aimC )
        
        '''
        `````````````````````````````
        
        mc.move(startJntPos[0],startJntPos[1],startJntPos[2], locatorTemple )
        mc.spaceLocator(n=aimLoc )
        mc.move(startJntPos[0]+poleVecX,startJntPos[1]+poleVecY,startJntPos[2]+poleVecZ,aimLoc  )
        mc.aimConstraint( aimLoc  ,locatorTemple  ,worldUpType='object',worldUpObject=startJnt[0])
        mc.delete( aimLoc   )

        '''
        
                    
    '''
        =========================================================
        ||                                                     ||
        ||控制器 部分 的 commands                              ||
        ||the part of control  shapes                          ||
        ||                                                     ||
        =========================================================
    '''   
                    
    
    
    def creatControls_command(self,type = 1 ,curName='',add=True):
        if type==1:
            pointInfo=[(-2,0, 0),(-2, 0, -1),( 0, 0 ,-1),( 0, 0, -2),( 2, 0 ,0 ),( 0, 0, 2),( 0 ,0 ,1),( -2, 0, 1),( -2, 0, 0)]
            pioint_K = [0,1,2,3,4,5,6,7,8]
            degreee = 1
        if type ==2 :   ###  facial ctrl 
            pointInfo = [(-0.5, 0.5, -0.5), (-0.5, -0.5, -0.5),( -0.5, -0.5, 0.5),( -0.5, 0.5, 0.5),(-0.5, 0.5, -0.5),( 0.5, 0.5 ,-0.5),( 0.5, 0.5, 0.5 ),( -0.5 ,0.5 ,0.5),( -0.5 ,-0.5, 0.5),( 0.5, -0.5, 0.5 ),( 0.5 ,0.5 ,0.5 ),( 0.5, 0.5, -0.5),( 0.5, -0.5, -0.5),( 0.5, -0.5, 0.5),( 0.5, -0.5,-0.5),(-0.5, -0.5, -0.5)]
            pioint_K = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
            degreee = 1
        
        if type == 3:  ##  eye ctrl
            pointInfo = [(-0.273501,0.398437,0),( 0.279265, 0.399227, 0),(0.284735, 0.4 ,0 ),( 0.287565, 0.405343 ,0 ),(0.334556 ,0.514181, 0 ),(0.553402, 0.840365 ,0 ),(1.2 ,1.108194, 0 ),(1.983612, 0.783612, 0 ),( 2.308194 ,0 ,0 ),(1.983612, -0.783612, 0),( 1.2, -1.108194, 0 ),(0.553402, -0.840365, 0 ),(0.334556 ,-0.514181, 0 ),( 0.28798, -0.40954 ,0 ),( 0.284735, -0.4 ,0 ),(0.27551, -0.400633 ,0 ),( -0.279436, -0.400321, 0 ),(-0.284735 ,-0.4,0 ),( -0.286778, -0.405624 ,0),( -0.334556 ,-0.514181, 0 ),( -0.553402, -0.840365 ,0 ),( -1.2 ,-1.108194 ,0 ),(-1.983612, -0.783612 ,0 ),( -2.308194 ,0 ,0 ),( -1.983612 ,0.783612, 0 ),( -1.2 ,1.108194 ,0 ),( -0.553402, 0.840365, 0 ),( -0.334556 ,0.514181, 0 ),( -0.289495, 0.408848 ,0 ),( -0.284735 ,0.4 ,0 ),( -0.273501, 0.398437, 0)]
            pioint_K = [0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,28,28]
            degreee = 3
            
        if type == 4:  ##  eye aim sec ctrl
            pointInfo = [(-1, 0, 0 ),( 0 ,0 ,0 ),(0 ,1, 0 ),( 0, 0 ,0 ),( 1, 0, 0 ),( 0, 0, 0),( 0 ,-1, 0) ]
            pioint_K = [0,1,2,3,4,5,6]
            degreee = 1
        if type == 5:  ##  circle 
            pass

            
            
        if type == 6:  ##  
            pass
        
        if type == 7:
            pointInfo = [(-1 ,0 ,0),( 1, 0, 0),( 0, 0 ,0),( 0, 0, 1),( 0, 0 ,-1 ),( 0, 0, 0),( 0 ,1 ,0 ),( 0 ,-1 ,0 ) ]
            pioint_K = [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ]
            degreee = 1
            
        if type == 8:
            pointInfo = [ (-1 ,4 ,0),( 1 ,4 ,0),( 1, 1, 0 ),( 4 ,1 ,0),( 4 ,-1, 0),( 1, -1 ,0 ),( 1, -4 ,0),(-1, -4 ,0 ),( -1 ,-1 ,0 ),( -4 ,-1, 0),( -4 ,1, 0 ),( -1, 1, 0),( -1, 4 ,0 ) ]
            pioint_K = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8, 9 , 10 , 11 , 12 ]
            degreee = 1
        
        if type == 9:
            pointInfo = [( 0 ,0 ,0.492662),( -0.0209175, 0 ,0.440895),( -0.0627526, 0, 0.476654 ),( -0.124432 ,0 ,0.464385 ),( -0.183981 ,0 ,0.44417 ),( -0.240383 ,0 ,0.416356 ),( -0.292672 ,0 ,0.381418),( -0.339953, 0, 0.339953 ),( -0.381418, 0 ,0.292672),( -0.416356, 0,0.240383 ),( -0.44417, 0 ,0.183981),( -0.464385 ,0 ,0.124432 ),( -0.476654 ,0 ,0.0627526 ),( -0.423016 ,0, 0 ),( -0.476654 ,0 ,-0.0627526 ),( -0.464385 ,0 ,-0.124432 ),( -0.44417 ,0 ,-0.183981 ),( -0.416356 ,0 ,-0.240383),( -0.381418, 0 ,-0.292672 ),( -0.339953, 0 ,-0.339953 ),( -0.292672, 0 ,-0.381418 ),( -0.240383, 0, -0.416356 ),(-0.183981 ,0 ,-0.44417 ),( -0.124432, 0 ,-0.464385 ),( -0.0627526 ,0 ,-0.476654 ),( 0, 0 ,-0.423016),( 0.0627526, 0 ,-0.476654 ),( 0.124432, 0 ,-0.464385 ),( 0.183981, 0, -0.44417),( 0.240383 ,0 ,-0.416356 ),( 0.292672, 0 ,-0.381418 ),( 0.339953 ,0 ,-0.339953 ),( 0.381418, 0, -0.292672 ),( 0.416356 ,0 ,-0.240383),( 0.44417 ,0, -0.183981 ),( 0.464385 ,0 ,-0.124432 ),( 0.476654, 0, -0.0627526),( 0.423016, 0 ,0 ),( 0.476654, 0 ,0.0627526 ),( 0.464385 ,0 ,0.124432 ),( 0.44417, 0 ,0.183981),( 0.416356, 0 ,0.240383 ),( 0.381418, 0 ,0.292672 ),(0.339953, 0 ,0.339953),( 0.292672 ,0 ,0.381418 ),( 0.240383, 0 ,0.416356 ),( 0.183981 ,0 ,0.44417 ),( 0.124432 ,0 ,0.464385 ),( 0.0627526, 0 ,0.476654 ),( 0.0209175, 0 ,0.440895 ),( 0 ,0 ,0.492662 ),( -0.0290887 ,0 ,0.5 ),( -0.087266, 0 ,0.49491),( -0.17188 ,0 ,0.472238 ),( -0.251272 ,0 ,0.435217 ),( -0.32303, 0 ,0.384972 ),( -0.384972 ,0 ,0.32303 ),( -0.435217 ,0, 0.251272 ),( -0.472238, 0 ,0.17188 ),( -0.49491 ,0 ,0.087266 ),( -0.502545, 0 ,0 ),( -0.49491 ,0 ,-0.087266 ),( -0.472238 ,0, -0.17188),( -0.435217 ,0, -0.251272 ),( -0.384972, 0 ,-0.32303 ),( -0.32303, 0, -0.384972 ),( -0.251272 ,0, -0.435217 ),( -0.17188 ,0, -0.472238 ),( -0.087266 ,0 ,-0.49491 ),( 0 ,0 ,-0.502545 ),( 0.087266 ,0 ,-0.49491),( 0.17188 ,0, -0.472238 ),( 0.251272 ,0, -0.435217),( 0.32303 ,0 ,-0.384972 ),( 0.384972 ,0 ,-0.32303),( 0.435217 ,0, -0.251272 ),( 0.472238 ,0, -0.17188 ),( 0.49491 ,0 ,-0.087266 ),( 0.502545 ,0 ,0),( 0.49491, 0 ,0.087266 ),( 0.472238, 0 ,0.17188 ),( 0.435217 ,0 ,0.251272 ),( 0.384972 ,0 ,0.32303 ),( 0.32303 ,0 ,0.384972 ),( 0.251272 ,0 ,0.435217 ),( 0.17188, 0 ,0.472238 ),( 0.087266 ,0 ,0.49491 ),( 0.0290887, 0 ,0.5 ),( 0 ,0 ,0.492662)]    
            pioint_K = [ 0 , 0 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , 83 , 84 , 85 , 86 , 86 , 86  ]
            degreee =3   
        
        
        if type == 10:    
            pointInfo =[(4, 0, 0 ),( 3 ,0 ,2),( 0 ,0 ,3 ),( -3 ,0 ,2 ),( -4 ,0 ,0 ),( -4, 0, 0 ),( -6 ,0, 0),( -6 ,0 ,0 ),( -5 ,0, 3 ),( -2 ,0 ,5 ),( 0 ,0 ,5 ),( 2 ,0 ,5 ),( 5 ,0 ,3 ),( 6 ,0 ,0 ),( 6 ,0 ,0 ),( 4 ,0, 0)]
        
            pioint_K = [ 0 , 0 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 13 , 13]
            degreee =3
        if type == 11:    
            pointInfo =[(0 ,0, -5 ),( 2 ,0, -5 ),( 3, 0 ,-4 ),( 3 ,0, -1 ),(2, 0, 0 ),( 2 ,0 ,1 ),( 3 ,0 ,3 ),( 3 ,0 ,5 ),( 2 ,0 ,6 ),( 0 ,0 ,6 ),( -2, 0, 6 ),( -3, 0 ,5 ),( -3 ,0 ,3 ),( -2 ,0 ,1 ),( -2 ,0 ,0 ),( -3 ,0, -1 ),( -3, 0 ,-4 ),( -2 ,0 ,-5 ),( 0, 0, -5)]
        
            pioint_K = [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 ]
            degreee =1
        
        if type == 12:    
            pointInfo =[(-2.0425, 1.067262, -0.267548 ),( -1.90608 ,1.604237, -0.291831 ),(-1.458906 ,2.07659, -0.291831),( -0.838961 ,2.38217 ,-0.291831 ),( 0, 2.472737 ,-0.291831),( 0.838961 ,2.38217 ,-0.291831 ),( 1.458906, 2.07659, -0.291831),( 1.90608 ,1.604237 ,-0.291831 ),( 2.0425 ,1.067262 ,-0.267548 ),( 2.0425, 1.067262, -0.267548 ),( 2.027141 ,1.067262 ,0.828746 ),( 2.36081, 1.067262 ,2.186062 ),( 1.992973, 1.067262 ,4.579428 ),( 0.476366, 1.067262, 4.587467 ),( 0, 0.893449, 4.84523 ),( -0.476366 ,1.067262, 4.587467 ),( -1.992973 ,1.067262 ,4.579428 ),( -2.36081 ,1.067262 ,2.186062 ),( -2.027141 ,1.067262, 0.828746 ),( -2.0425, 1.067262, -0.267548 ),( -2.316573, 1.067262 ,-2.016397 ),( -2.355726 ,1.067262 ,-3.127629 ),( -2.303522, 1.067262 ,-3.323396 ),( -1.664017 ,1.067262 ,-3.745478 ),( -0.907053 ,1.067262 ,-3.778298 ),( 0 ,1.324136 ,-3.778298 ),( 0.907053 ,1.067262 ,-3.778298 ),( 1.664017 ,1.067262, -3.745478 ),( 2.303522, 1.067262, -3.323396 ),( 2.355726 ,1.067262, -3.127629 ),( 2.316573, 1.067262 ,-2.016397 ),( 2.0425, 1.067262 ,-0.267548 ),( 2.027141, 1.067262, 0.828746 ),( 2.36081 ,1.067262 ,2.186062 ),( 1.992973, 1.067262 ,4.579428 ),( 0.476366 ,1.067262 ,4.587467 ),( 0, 0.893449 ,4.84523 ),( 0 ,0.893449 ,4.84523 ),( 0 ,0.893449 ,4.84523 ),( 0 ,1.96364 ,3.699991 ),( 0 ,2.289918 ,2.186062 ),( 0 ,2.316021 ,0.828746 ),( 0 ,2.472737 ,-0.291831 ),( 0 ,2.733656, -2.016397 ),( 0 ,2.77281, -2.708107 ),( 0 ,2.720605 ,-2.903873),( 0, 2.081101, -3.517276 ),( 0, 1.324136, -3.778298)]
        
            pioint_K = [0 , 0 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 45 , 45  ]
            degreee =3        
        
        if type == 13:
            pointInfo = [( 0,0,3 ) , (3, 1.196284, 3 ),(6, 0.503884, 2),( 7, 2.272208, 0 ),( 6 ,0.503884 ,-2 ),( 3 ,1.196284 ,-3 ),( 0 ,0 ,-3)]
            pioint_K = [ 0 , 0 , 0 , 1 , 2 ,3 , 4 ,4 , 4 ]
            degreee =3        
        
        if add == True:
            ctrlAdd = str(curName) + '_temple'
            if type == 5 :
                mc.circle(c=(0,0,0),nr=(0,1,0),sw=360,r=1,d=3,ut = 0,tol= 0.01,s=8,ch=False,n=ctrlAdd)
            elif type == 6 :
            
                mc.circle(c=(0,0,0),nr=(0,1,0),sw=360,r=1,d=1,ut = 0,tol= 0.01,s=4,ch=False,n=ctrlAdd)
                
            else:
            
                mc.curve(d = degreee ,p = pointInfo,k= pioint_K ,n=ctrlAdd )    
            Templeshape=mc.listRelatives(ctrlAdd,s=True)
            mc.parent(Templeshape,curName,add=True,s=True)
            mc.delete(ctrlAdd)
            CtrlShapeAdd = mc.rename(Templeshape,str(curName)+'Shape')
            
        else:
            if type == 5 :
                mc.circle(c=(0,0,0),nr=(0,1,0),sw=360,r=1,d=3,ut = 0,tol= 0.01,s=8,ch=False,n=curName)
            elif type == 6 :
            
                mc.circle(c=(0,0,0),nr=(0,1,0),sw=360,r=1,d=1,ut = 0,tol= 0.01,s=4,ch=False,n=curName)
        
            else:
                mc.curve(d = degreee ,p = pointInfo,k= pioint_K ,n = curName )  
    
    def moveCurveHull(self,curveName = '',tx = 0,ty = 0, tz = 0 ):

        curveshapes=mc.listRelatives(curveName,s=True)
        for curveshape  in curveshapes:
            spans=mc.getAttr(str(curveshape)+'.spans')
            degree=mc.getAttr(str(curveshape)+'.degree')
            pointsMounts=spans+degree
        
            mc.move( tx,ty,tz,str(curveshape) + '.cv[0:' + str(pointsMounts)  +']' ,os=True, r=True )
    
    
    def rotateCurveHull(self, curveName = '',rx = 0,ry = 0, rz = 0 ,centerP = 1 ):
        curveshapes=mc.listRelatives(curveName,s=True)
        
        cvAllX=[]
        cvAllY=[]
        cvAllZ=[]

        for curveshape in curveshapes:
            spans=mc.getAttr(str(curveshape)+'.spans')
            degree=mc.getAttr(str(curveshape)+'.degree')
            pointsMounts=spans+degree

            for i in range(pointsMounts):

                pointcvPos=mc.xform(str(curveshape)+'.cv['+str(i)+']',q=True,t=True,ws=True)

                cvAllX.append(pointcvPos[0])
                cvAllY.append(pointcvPos[1])
                cvAllZ.append(pointcvPos[2])
                
        pointCVposXMin=cvAllX[0]
        pointCVposYMin=cvAllY[0]
        pointCVposZMin=cvAllZ[0]
        
        pointCVposXMax=cvAllX[0]
        pointCVposYMax=cvAllY[0]
        pointCVposZMax=cvAllZ[0]
        


        for k in range(len(cvAllX)):
            pointCVposXMin=min(pointCVposXMin,cvAllX[k])
            pointCVposXMax=max(pointCVposXMax,cvAllX[k])
            
            pointCVposYMin=min(pointCVposYMin,cvAllY[k])
            pointCVposYMax=max(pointCVposYMax,cvAllY[k])
            
            pointCVposZMin=min(pointCVposZMin,cvAllZ[k])
            pointCVposZMax=max(pointCVposZMax,cvAllZ[k])
        
        centerPivetX=(pointCVposXMin+pointCVposXMax)/2
        centerPivetY=(pointCVposYMin+pointCVposYMax)/2
        centerPivetZ=(pointCVposZMin+pointCVposZMax)/2
        
        if centerP==1:
            centerPivet=[centerPivetX,centerPivetY,centerPivetZ]
            
        else:
            centerPivet = mc.xform(curveName , q=True ,t =True,ws=True)
        mc.rotate( rx,ry,rz,str(curveshape) + '.cv[0:' + str(pointsMounts)  +']' ,os=True, r=True,p = centerPivet )
            
        
    def scaleCurveHull(self,curvename,scalX,scalY,scalZ):
        curveshapes=mc.listRelatives(curvename,s=True)
        
        cvAllX=[]
        cvAllY=[]
        cvAllZ=[]

        for curveshape in curveshapes:
            spans=mc.getAttr(str(curveshape)+'.spans')
            degree=mc.getAttr(str(curveshape)+'.degree')
            pointsMounts=spans+degree

            for i in range(pointsMounts):

                pointcvPos=mc.xform(str(curveshape)+'.cv['+str(i)+']',q=True,t=True,ws=True)

                cvAllX.append(pointcvPos[0])
                cvAllY.append(pointcvPos[1])
                cvAllZ.append(pointcvPos[2])
                
        pointCVposXMin=cvAllX[0]
        pointCVposYMin=cvAllY[0]
        pointCVposZMin=cvAllZ[0]
        
        pointCVposXMax=cvAllX[0]
        pointCVposYMax=cvAllY[0]
        pointCVposZMax=cvAllZ[0]
        


        for k in range(len(cvAllX)):
            pointCVposXMin=min(pointCVposXMin,cvAllX[k])
            pointCVposXMax=max(pointCVposXMax,cvAllX[k])
            
            pointCVposYMin=min(pointCVposYMin,cvAllY[k])
            pointCVposYMax=max(pointCVposYMax,cvAllY[k])
            
            pointCVposZMin=min(pointCVposZMin,cvAllZ[k])
            pointCVposZMax=max(pointCVposZMax,cvAllZ[k])
        
        centerPivetX=(pointCVposXMin+pointCVposXMax)/2
        centerPivetY=(pointCVposYMin+pointCVposYMax)/2
        centerPivetZ=(pointCVposZMin+pointCVposZMax)/2
        
        centerPivet=[centerPivetX,centerPivetY,centerPivetZ]
            
        #mc.select(str(curvename)+'.cv[0:'+str((pointsMounts-1))+']')
        
        for curveshape in curveshapes:
            
            spans=mc.getAttr(str(curveshape)+'.spans')
            degree=mc.getAttr(str(curveshape)+'.degree')
            pointsMounts=spans+degree
            
            
            cv = str(curveshape)+'.cv[0:'+str((pointsMounts-1))+']'
            mc.scale(scalX,scalY,scalZ,cv,r=True,p=centerPivet)
            
    def normalizeHull(self,curvename):
        curveshapes=mc.listRelatives(curvename,s=True)
        
        cvAllX=[]
        cvAllY=[]
        cvAllZ=[]

        for curveshape in curveshapes:
            spans=mc.getAttr(str(curveshape)+'.spans')
            degree=mc.getAttr(str(curveshape)+'.degree')
            pointsMounts=spans+degree

            for i in range(pointsMounts):

                pointcvPos=mc.xform(str(curveshape)+'.cv['+str(i)+']',q=True,t=True,ws=True)

                cvAllX.append(pointcvPos[0])
                cvAllY.append(pointcvPos[1])
                cvAllZ.append(pointcvPos[2])
                
        pointCVposXMin=cvAllX[0]
        pointCVposYMin=cvAllY[0]
        pointCVposZMin=cvAllZ[0]
        
        pointCVposXMax=cvAllX[0]
        pointCVposYMax=cvAllY[0]
        pointCVposZMax=cvAllZ[0]
        


        for k in range(len(cvAllX)):
            pointCVposXMin=min(pointCVposXMin,cvAllX[k])
            pointCVposXMax=max(pointCVposXMax,cvAllX[k])
            
            pointCVposYMin=min(pointCVposYMin,cvAllY[k])
            pointCVposYMax=max(pointCVposYMax,cvAllY[k])
            
            pointCVposZMin=min(pointCVposZMin,cvAllZ[k])
            pointCVposZMax=max(pointCVposZMax,cvAllZ[k])
        
        centerPivetX=(pointCVposXMin+pointCVposXMax)/2
        centerPivetY=(pointCVposYMin+pointCVposYMax)/2
        centerPivetZ=(pointCVposZMin+pointCVposZMax)/2
        
        centerPivet=[centerPivetX,centerPivetY,centerPivetZ]
        

        
        position = mc.xform( curvename ,q=True ,t=True,ws =True)
        for curveshape in curveshapes:
            
            spans=mc.getAttr(str(curveshape)+'.spans')
            degree=mc.getAttr(str(curveshape)+'.degree')
            pointsMounts=spans+degree
            
            
            cv = str(curveshape)+'.cv[0:'+str((pointsMounts-1))+']'
            mc.move( ( position[0] -centerPivet[0] ),( position[1] -centerPivet[1]   ),(  position[2]-centerPivet[2] ), cv , r=True)
    
    
    
    '''
        =========================================================
        ||                                                     ||
        ||层级关系处理 部分 的 commands                        ||
        ||the part of the relations parent                     ||
        ||                                                     ||
        =========================================================
    '''   
    def sequenceParent(self,  obj = ['','']):
        objsel = obj
        mountsobj=len(objsel)
        for i in range(mountsobj-1):
            mc.parent(objsel[i],objsel[i+1])
    

    '''
        =========================================================
        ||                                                     ||
        ||绑定设置 部分 的 commands                            ||
        ||the part of the rigging part                         ||
        ||                                                     ||
        =========================================================
    '''   

    
    def createNonroll_jnt(self , startJnt = '' ,endEffctor = '' , parentObj ='' ,followObj = '' ):
        startJntSuff = str( startJnt  ).split('_')[-1] 
        endEffctorSuff = str( endEffctor  ).split('_')[-1] 
        

        nonroll_jnt =  str(startJnt).replace( startJntSuff , 'nonroll')
        nonroll_jntend =   str(endEffctor).replace( endEffctorSuff , 'nonrollend')
        
        self.LZ_creatJoint( startJnt ,nonroll_jnt   )
        self.LZ_creatJoint( endEffctor ,nonroll_jntend   )
        
        mc.parent( nonroll_jntend , nonroll_jnt )
        
        ikhadle_name = str(nonroll_jnt)+'_ikHandle'
        ikhadlePointCon_name = str(nonroll_jnt)+'_ikHandle_pointCon'
        mc.group(em=True,n = ikhadlePointCon_name )
        
        mc.ikHandle(sj = nonroll_jnt ,ee = nonroll_jntend ,n = ikhadle_name ,solver = 'ikSCsolver' )
        
        self.snapObj2Aim( obj = ikhadlePointCon_name ,aimobj =ikhadle_name , Translate = True ,rotation = True)
        mc.pointConstraint( ikhadlePointCon_name , ikhadle_name )
        
        mc.parent( ikhadle_name , parentObj )
        mc.parent( ikhadlePointCon_name , followObj  )
        mc.parent( nonroll_jnt , parentObj )
        